package com.sc.nft.dao;

import cn.hutool.core.lang.Assert;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.sc.nft.entity.EcologyPool;
import com.sc.nft.enums.EcologyPoolLinkTypeEnum;
import com.sc.nft.enums.EcologyPoolTypeEnum;
import com.sc.nft.exception.GlobalRunTimeException;
import com.sc.nft.mapper.EcologyPoolMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Repository;

import java.math.BigDecimal;
import java.util.List;
import java.util.Objects;

/**
 * @author 刘国航
 * @since 2024/7/15
 */
@Slf4j
@Repository
public class EcologyPoolDao extends ServiceImpl<EcologyPoolMapper, EcologyPool> {

    /**
     * 扣减积分
     *
     * @param likeCount
     * @param id
     * @return
     */
    public int reduceLikeCount(BigDecimal likeCount, Long id, Integer version) {
        return baseMapper.reduceLikeCount(likeCount, EcologyPoolLinkTypeEnum.POINTS, id, version);
    }

    /**
     * 新增积分
     *
     * @param likeCount
     * @param id
     * @return
     */
    public int plusLikeCount(BigDecimal likeCount, Long id, Integer version) {
        return baseMapper.plusLikeCount(likeCount, EcologyPoolLinkTypeEnum.POINTS, id, version);
    }

    /**
     * 获取优秀品牌生态池
     *
     * @return
     */
    public EcologyPool getExcellentBrand() {
        LambdaQueryWrapper<EcologyPool> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(EcologyPool::getLinkType, EcologyPoolLinkTypeEnum.POINTS);
        wrapper.eq(EcologyPool::getPoolType, EcologyPoolTypeEnum.EXCELLENT_BRAND.getCode());
        wrapper.orderByDesc(EcologyPool::getId);
        wrapper.last("limit 1");
        return baseMapper.selectOne(wrapper);
    }

    public List<EcologyPool> listPoolDataByDaoIds(List<Long> ids) {
        LambdaQueryWrapper<EcologyPool> wrapper = new LambdaQueryWrapper<>();
        wrapper.in(EcologyPool::getDaoId, ids);
        wrapper.eq(EcologyPool::getPoolType, EcologyPoolTypeEnum.BRAND.getCode());
        return list(wrapper);
    }

    public List<EcologyPool> getListByTypes(List<EcologyPoolTypeEnum> typeList, EcologyPoolLinkTypeEnum linkType, Long daoId) {
        LambdaQueryWrapper<EcologyPool> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.in(CollectionUtils.isNotEmpty(typeList), EcologyPool::getPoolType, typeList);
        queryWrapper.eq(Objects.nonNull(linkType), EcologyPool::getLinkType, linkType);
        queryWrapper.eq(Objects.nonNull(daoId), EcologyPool::getDaoId, daoId);
        return baseMapper.selectList(queryWrapper);
    }

    public List<EcologyPool> getListByTypes(List<EcologyPoolTypeEnum> typeList, EcologyPoolLinkTypeEnum linkType) {
        LambdaQueryWrapper<EcologyPool> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.in(CollectionUtils.isNotEmpty(typeList), EcologyPool::getPoolType, typeList);
        queryWrapper.eq(Objects.nonNull(linkType), EcologyPool::getLinkType, linkType);
        return baseMapper.selectList(queryWrapper);
    }

    public EcologyPool getByType(EcologyPoolTypeEnum type, EcologyPoolLinkTypeEnum linkType) {
        LambdaQueryWrapper<EcologyPool> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.eq(EcologyPool::getPoolType, type);
        queryWrapper.eq(EcologyPool::getLinkType, linkType);
        queryWrapper.orderByDesc(EcologyPool::getId);
        queryWrapper.last("limit 1");
        return baseMapper.selectOne(queryWrapper);
    }

    public EcologyPool getByTypeAndDaoId(EcologyPoolTypeEnum type, EcologyPoolLinkTypeEnum linkType, Long daoId) {
        LambdaQueryWrapper<EcologyPool> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.eq(EcologyPool::getPoolType, type);
        queryWrapper.eq(EcologyPool::getLinkType, linkType);
        queryWrapper.eq(EcologyPool::getDaoId, daoId);
        queryWrapper.orderByDesc(EcologyPool::getId);
        queryWrapper.last("limit 1");
        return baseMapper.selectOne(queryWrapper);
    }

    public EcologyPool getByTypeAndDaoIdUserId(EcologyPoolTypeEnum type, EcologyPoolLinkTypeEnum linkType, Long daoId, Long userId) {
        LambdaQueryWrapper<EcologyPool> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.eq(EcologyPool::getPoolType, type);
        queryWrapper.eq(EcologyPool::getLinkType, linkType);
        queryWrapper.eq(EcologyPool::getDaoId, daoId);
        queryWrapper.eq(EcologyPool::getUserId, userId);
        queryWrapper.orderByDesc(EcologyPool::getId);
        queryWrapper.last("limit 1");
        return baseMapper.selectOne(queryWrapper);
    }

    public List<EcologyPool> getByTypeAndDaoIdUserIdList(EcologyPoolTypeEnum type, EcologyPoolLinkTypeEnum linkType, Long daoId, List<Long> userIdList) {
        LambdaQueryWrapper<EcologyPool> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.eq(EcologyPool::getPoolType, type);
        queryWrapper.eq(EcologyPool::getLinkType, linkType);
        queryWrapper.eq(EcologyPool::getDaoId, daoId);
        queryWrapper.in(EcologyPool::getUserId, userIdList);
        return baseMapper.selectList(queryWrapper);
    }

    /**
     * 增加积分
     *
     * @param id
     * @param linkCount
     */
    public void increasePoints(Long id, BigDecimal linkCount, Integer version) {
        Assert.isTrue(linkCount.compareTo(BigDecimal.ZERO) > 0, () -> new GlobalRunTimeException("积分必须大于0"));
        LambdaUpdateWrapper<EcologyPool> updateWrapper = Wrappers.lambdaUpdate();
        updateWrapper.setSql("link_count = link_count + " + linkCount);
        updateWrapper.eq(EcologyPool::getId, id);
        if (baseMapper.update(new EcologyPool().setVersion(version), updateWrapper) == 0) {
            throw new GlobalRunTimeException("更新生态池积分失败");
        }
    }

    /**
     * 减少积分
     *
     * @param id
     * @param linkCount
     */
    public void reducePoints(Long id, BigDecimal linkCount, Integer version) {
        Assert.isTrue(linkCount.compareTo(BigDecimal.ZERO) > 0, () -> new GlobalRunTimeException("积分必须大于0"));
        LambdaUpdateWrapper<EcologyPool> updateWrapper = Wrappers.lambdaUpdate();
        updateWrapper.setSql("link_count = link_count - " + linkCount);
        updateWrapper.eq(EcologyPool::getId, id);
        updateWrapper.ge(EcologyPool::getLinkCount, linkCount);
        if (baseMapper.update(new EcologyPool().setVersion(version), updateWrapper) == 0) {
            throw new GlobalRunTimeException("更新生态池积分失败");
        }
    }

    /**
     * 查询积分
     *
     * @param type
     * @param linkType
     * @param daoId
     * @param userId
     * @return
     */
    public EcologyPool getOneByTypeAndDaoIdUserId(EcologyPoolTypeEnum type, EcologyPoolLinkTypeEnum linkType, Long daoId, Long userId) {
        LambdaQueryWrapper<EcologyPool> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.eq(EcologyPool::getPoolType, type);
        queryWrapper.eq(EcologyPool::getLinkType, linkType);
        queryWrapper.eq(EcologyPool::getDaoId, daoId);
        queryWrapper.eq(Objects.nonNull(userId), EcologyPool::getUserId, userId);
        queryWrapper.orderByDesc(EcologyPool::getId);
        queryWrapper.last("limit 1");
        return baseMapper.selectOne(queryWrapper);
    }

    /**
     * 更新生态池名称
     *
     * @param id
     * @param poolName
     * @param version
     */
    public void updatePoolName(Long id, String poolName, Integer version) {
        LambdaUpdateWrapper<EcologyPool> updateWrapper = Wrappers.lambdaUpdate();
        updateWrapper.set(EcologyPool::getPoolName, poolName);
        updateWrapper.setSql("version = version + 1");
        updateWrapper.eq(EcologyPool::getId, id);
        updateWrapper.eq(EcologyPool::getVersion, version);
        if (baseMapper.update(new EcologyPool(), updateWrapper) == 0) {
            throw new GlobalRunTimeException("更新生态池名称失败");
        }
    }

}
